import React from 'react';
import {Button, Col, Input, Pagination, Row, Spin, Tabs, Tooltip} from 'antd';
import {
    isEmpty,
    map,
    isFunction,
    keys,
    isArray,
    forEach,
    filter,
    unionWith,
    clone,
    findIndex,
    omit,
    isString
} from "lodash-es";
import BaseComp from "../Base/BaseComp";
import TableComp from "../TableComp";
import TreeComp from "../TreeComp/TreeComp";
import {DoubleRightOutlined} from "@ant-design/icons";
import PropTypes from "prop-types";
import ModalComp from "../ModalItem/ModalComp";
import FinderHelper from "../FinderSelect/FinderHelper";
import FinderCache from "../FinderSelect/FinderCache";
import {comboApi} from "../Config/GlobalApi";
import {getRandomKey, OrderField, QueryDataConf, QueryFilter} from 'jh-utils'
import {jhMessage} from "../../utils/base";
import styles from './index.module.less'
import {ComponentType} from "../Config";

const {Search} = Input;
const {TabPane} = Tabs;

const staticProps = {
    /**
     * 弹框的标题
     */
    title: PropTypes.string,
    /**
     * 是否显示弹框
     */
    visible: PropTypes.bool,
    /**
     * “确认选择”之后的回调
     */
    onOk: PropTypes.func,
    /**
     * “取消选择”之后的回调
     */
    onCancel: PropTypes.func,

    finderCode: PropTypes.string,
    appCode: PropTypes.string,
    /**
     * 是否可以请求数据
     */
    canFetchData: PropTypes.bool,
    /**
     * 是否“多选”。默认 false
     */
    multi: PropTypes.bool,
    /**
     * 是否显示已选中的数据。默认显示
     */
    showSelected: PropTypes.bool,
    /**
     * 表格-默认已选中的数据数据
     */
    defaultSelectedRows: PropTypes.arrayOf(PropTypes.object),

    /**
     * 请求“查找器-配置信息”的方法
     * @type {function(ajaxData: {}): Promise}
     */
    fetchConf: PropTypes.func,

    /**
     * 请求“左侧分类列表”数据
     * @type {function(cateSelNode: {}):Promise}
     * @param cateSelNode {{}} 左侧选中的节点
     * Promise 返回的第一个参数，即列表数据
     */
    fetchCateList: PropTypes.func,
    /**
     * 左侧 TreeComp 组件的属性
     */
    cateTreeProps: PropTypes.object,

    /**
     * 请求“右侧表格”数据
     * @type {function(ajaxData: {
     *     finderCode: string,
     *     startIndex: number,
     *     maxResults: number,
     *     filter: {}
     * }):Promise}
     * Promise.then 回调中的第一个参数，即列表数据
     */
    fetchList: PropTypes.func,
    /**
     * 右侧 TableComp 组件的属性
     */
    tableProps: PropTypes.func
};

/**
 * 查找器-弹框组件
 */
export default class FinderModal extends BaseComp {

    static propTypes = {
        ...BaseComp.propTypes,
        ...staticProps
    };

    static defaultProps = {
        multi: false,  // 默认单选
        showSelected: true, // 默认显示已选中的数据
        canFetchData: true,
        belong: {}
    };

    moreCommonProps() {
        return [...super.moreCommonProps(), ...keys(staticProps)]
    }

    /**
     * 查找器的 appCode
     * @return {*}
     */
    get appCode4Finder() {
        return this.finderHelper.getAppCode4Finder();
    }

    /**
     * 查找器-配置
     * @type {{}}
     */
    set finderConf(value) {
        FinderCache.addConfCache(this.getPropsByName('finderCode'), value);
    }

    get finderConf() {
        return FinderCache.getConfCache(this.getPropsByName('finderCode'));
    }

    randomKey = getRandomKey();

    /**
     * 左侧数组件的实例
     * @type { TreeComp | null}
     */
    treeIns = null;


    /**
     * 左侧分类列表的过滤器
     * @type { QueryFilter | {}}
     */
    categoryFilter = {};

    /**
     *
     * @type { QueryFilter | {}}
     */
    filter = {};
    queryFields = [];
    splitQuery = false;

    searchData = {
        fuzzyMatch: 'code,name,spellCode',
        search: '',
        filterData: {}
    };

    /**
     * 右侧表格组件实例
     * @type { TableComp | null}
     */
    tableIns = null;

    /**
     * 自定义扩展字段表格实例
     * @type { TableComp | null}
     */
    tableExtIns = null;
    _selectedRows = [];

    get selectedRows() {
        return this._selectedRows;
    }

    set selectedRows(value) {
        this._selectedRows = value;

        if (this.selectedBtnIns) { // 更新已选择的数量
            let cnt = this._selectedRows ? this._selectedRows.length : 0;
            this.selectedBtnIns.setCompProps({cnt});
        }

        if (this.tableIns && this.tableIns.setSelectedKeys) {
            this.tableIns.setSelectedKeys(map(this.selectedRows, (row) => (row.id)));
        }

        if (this.tableExtIns && this.tableExtIns.setSelectedKeys) {
            this.tableExtIns.setSelectedKeys(map(this.selectedRows, (row) => (row.id)));
        }
    }

    /**
     * 已选中表格组件实例
     * @type { TableComp | null}
     */
    selectedTableIns = null;

    /**
     * 是否过滤已选中的数据
     * @type {boolean}
     */
    filterSelected = false;

    constructor(props) {
        super(props);
        this.finderHelper = new FinderHelper(this);
    }

    initState(props) {
        let superState = super.initState(props);
        return {
            ...superState,
            loading: false, // 是否正在加载“当前组件”
            cateLoading: false, // 是否正在加载“查找器配置”
            listLoading: false, // 是否正在加载“查找器配置”
            activeTabKey: 'list',
            // 是否存在自定义扩展字段
            extendedEnable: false,
            listPage: {
                total: 0, // 总记录数
                pageSize: 20, // 每页显示的记录数
                current: 1, // 当前页
                // pages: 0, // 总页数
            }
        }
    }

    componentDidMount() {
        super.componentDidMount();
        if (this.props.visible) {
            this._mountFunc();
        }
    }

    componentDidUpdate(prevProps, prevState) {

        if (!prevProps.visible && this.props.visible) {
            this._mountFunc();
        }
    }

    _mountFunc() {
        // 先执行一次 beforeFetchCb ，以更新属性值
        this.runBeforeCbs();

        if (false === this.getPropsByName('canFetchData')) return;

        this.selectedRows = clone(this.getPropsByName('defaultSelectedRows')) || [];
        // 获取查找器配置
        this.finderHelper.getFinderConf(() => {
            this.setPropsByConf();
            this.fetchCateList();
            this.fetchList();
        });
    }

    componentWillUnmount() {
        super.componentWillUnmount();

        const finderCode = this.getPropsByName('finderCode');
        if (finderCode) {
            FinderCache.removeLoadingIns(finderCode, this.randomKey);
        }
    }

    /**
     * 根据查找器配置（finderConf）更新属性值
     */
    setPropsByConf() {
        const newProps = {};
        let title = this.getPropsByName('title');

        if (isEmpty(title) || '-' === title) {
            const {name} = this.finderConf;
            newProps.title = name;
        }
        this.setCompProps(newProps);
    }

    /**
     * 是否多选
     */
    isMulti() {
        return this.getPropsByName('multi');
    }

    /**
     * “表格-发请求之前”的回调方法数组
     * @type {[function(compIns)]}
     */
    editBeforeCbs = [];

    /**
     * 设置“表格-发请求之前”回调处理。重复调用此方法，可实现“多次事件回调的绑定”
     * @param cb {function(compIns: {})} // compIns 是当前编辑组件的实例
     */
    addEditBeforeHandler(cb) {
        if (isFunction(cb)) {
            this.editBeforeCbs.push(cb);
        }
    }

    /**
     * 执行 editBeforeCbs
     */
    runBeforeCbs() {
        // console.log('FinderModal runBeforeCbs:', this.editBeforeCbs);
        forEach(this.editBeforeCbs, (cb) => {
            cb(this);
        });
    }

    /**
     * 请求枚举数据
     * @param ajaxData
     * @return {null}
     */
    fetchComboFunc(ajaxData) {
        return this.reqGet(comboApi.api, ajaxData);
    }

    /**
     * 获取左侧列表列表
     * @param params {{search?:string}} 请求参数
     * @return {Promise<unknown>|boolean|*}
     */
    fetchCateList(params = {}) {
        const {categorized, treeCategory, categorySelector, categoryCode, categoryType} = this.finderConf;

        if (!categorized) {
            return false;
        }

        const {search} = params;
        // 如果是枚举分类，则调用枚举接口
        if (categorySelector) {

            this._fetchCateFunc(
                () => {
                    return this.fetchComboFunc({code: categorySelector});
                },
                (rsp) => {
                    let newList = [];
                    if (rsp && rsp.status === 200) {
                        let rspData = rsp.data;
                        newList = isArray(rspData) ? rspData : (
                            isArray(rspData.options) ? rspData.options : []
                        );
                        newList = map(newList, (item) => ({
                            ...item,
                            key: item.code || getRandomKey(),
                            title: item.name
                        }))
                    }
                    this.treeIns.setData(newList);
                }
            );

        } else if (categoryCode || categoryType) {
            const queryConf = new QueryDataConf();
            queryConf.filter = new QueryFilter(QueryFilter.AND);
            queryConf.filter.formatBySearchData({
                fuzzyMatch: this.searchData.fuzzyMatch,
                search
            });
            if (this.categoryFilter && this.categoryFilter.toJson) {
                queryConf.filter.children.push(this.categoryFilter);
            }

            // 如果是树状分类，构建相应过滤条件
            if (treeCategory) {
                // 只查询要根节点
                const childFilter = queryConf.filter.and();
                childFilter.orEqual("parentIsn", "");
                childFilter.orIsNull("parentIsn");
            }
            this.fetchTreeCate(queryConf);
        }


    }

    fetchTreeCate(queryConf, parentNode = null) {
        const {treeCategory, categoryCode, categoryType} = this.finderConf;
        const fetchCateFunc = this.finderHelper.getFetchListFunc();

        if (isFunction(fetchCateFunc)) {
            queryConf.startIndex = 0;
            queryConf.maxResults = 300;

            // 如果是树状分类，构建相应过滤条件
            if (treeCategory) {
                queryConf.queryFields.push("isn");
                queryConf.queryFields.push("parentIsn");
                queryConf.queryFields.push("rootIsn");
                queryConf.queryFields.push("leftValue");
                queryConf.queryFields.push("rightValue");
                queryConf.queryFields.push("layer");
            }

            this.customTreeCateQueryConf(queryConf, parentNode);

            const ajaxData = queryConf.toJson();
            if (isEmpty(ajaxData.finderCode) && categoryCode)
                ajaxData.finderCode = categoryCode;
            if (isEmpty(ajaxData.javaType) && categoryType)
                ajaxData.javaType = categoryType;

            this._fetchCateFunc(
                () => {
                    return fetchCateFunc(ajaxData);
                },
                (rsp) => {
                    let isRoot = isEmpty(parentNode) || isEmpty(parentNode.key);
                    let newList = [];
                    if (rsp && rsp.status === 200) {
                        let rspData = rsp.data;
                        newList = isArray(rspData) ? rspData : (
                            isArray(rspData.results) ? rspData.results : []
                        );
                        newList = this.customTreeCateData(newList, parentNode);
                    }
                    // 如果有父节点，说明当前是获取“左侧分类树”的子节点列表，
                    // 则将获取到的数据，追加到父节点的 children
                    if (!isRoot) {
                        this.treeIns.updateDataByKey(parentNode.key, newList);
                    } else {
                        this.treeIns.setData(newList);
                        if (true !== this.firstLoadedCate) {
                            this.firstLoadedCate = true; // 标识首次加载完“左侧列表”
                            this.firstLoadedCateCb();
                        }
                    }
                }
            );
        }
    }

    _fetchCateFunc(func, afterCb) {
        this.setState({cateLoading: true});

        const fetchReturn = func();

        if (fetchReturn instanceof Promise) {
            return fetchReturn.then(rsp => {
                this.setState({cateLoading: false});
                return afterCb(rsp);
            }).catch(() => {
                this.setState({cateLoading: false});
            });
        } else {
            this.setState({cateLoading: false});
            return new Promise((resolve => {
                resolve([]);
            }))
        }
    }

    /**
     * 获取表格数据
     */
    fetchList() {
        const {pageSize, current} = this.state.listPage;
        const reObj = this.finderHelper.getAjaxData4List({pageSize, current});

        if (false === reObj) return false;

        this.setState({listLoading: true});

        const {ajaxData, fetchFunc} = reObj;
        const fetchReturn = fetchFunc(ajaxData, {}, this);

        if (fetchReturn instanceof Promise) {
            return fetchReturn.then(rsp => {

                const newState = {listLoading: false};
                let newList = [];

                if (rsp && rsp.status === 200) {
                    // console.log('rsp', rsp);
                    let rspData = rsp.data || {};
                    newList = isArray(rspData) ? rspData : (rspData.results || rspData.records);

                    newList = this.customTableList(newList);
                    newState.listPage = {
                        total: rspData.resultCount,
                        pageSize: rspData.maxResults || pageSize,
                        current: current
                    };
                }
                this.tableIns.setData(newList, () => {
                    this.setState(newState);
                });
                return rsp;
            }).catch(() => {
                this.setState({listLoading: false});
            });
        } else {
            this.setState({listLoading: false});
        }

    }

    /**
     * (此方法会在每次请求列表数据之前执行)
     * 个性化处理右侧表格的查询条件 QueryDataConf。
     * @param queryConf {QueryDataConf} 查询条件辅助类的实例。直接修改此实例即可。
     */
    customQueryConf(queryConf) {

        let appDendroid = this.getPropsByName('appDendroid') || this.finderConf.appDendroid;
        // appDendroid=true，说明查找器本身是“树状结构”数据，如果没有选中左侧节点，则默认获取根节点数据
        if (appDendroid && isEmpty(this.searchData.filterData)) {
            // 只查询要根节点
            const childFilter = queryConf.filter.and();
            childFilter.orEqual("parentIsn", "");
            childFilter.orIsNull("parentIsn");
        }

    }

    /**
     * 个性化处理右侧表格的数据
     * @param list
     * @return {Array}
     */
    customTableList(list) {
        return map(list, (item) => {
            delete item.children; // 表格不要出现“子表格形式”

            return {
                key: item.id,
                ...item
            }
        });
    }

    /**
     * 个性化处理左侧树列表的查询条件 QueryDataConf
     * @param queryConf {QueryDataConf}
     * @param parentNode
     */
    customTreeCateQueryConf(queryConf, parentNode = null) {

    }

    /**
     * 个性化处理左侧树列表的数据
     * @param treeList
     * @param parentNode
     * @return {Array}
     */
    customTreeCateData(treeList, parentNode) {
        let isRoot = isEmpty(parentNode) || isEmpty(parentNode.key);

        return map(treeList, (item) => {
            return {
                ...omit(item, ['children']),
                key: item.isn || getRandomKey(),
                title: item.name,
                isRoot
            };
        })
    }

    /**
     * 首次加载完“左侧数据”之后的回调
     */
    firstLoadedCateCb() {
    }

    /**
     * 选择节点之后的回调
     * @param keys {string[]} 选中的节点
     * @param event {{selected: boolean, selectedNodes, node, event}}
     */
    hdlSelectNode(keys, {node}) {
        this.selectedNode = node;
        this.searchData.filterData = {};
        let {appDendroid, categoryCode, categorySelector, treeCategory, categoryField, categoryType} = this.finderConf;

        // appDendroid=true，说明查找器本身是“树状结构”数据，左侧数据得一级一级的获取
        if (appDendroid) {
            // 获取当前节点的子节点列表
            const queryConf = new QueryDataConf();
            queryConf.filter = new QueryFilter(QueryFilter.AND);
            queryConf.filter.andEqual('parentIsn', node.isn);
            this.fetchTreeCate(queryConf, node);

            // 构建“右侧表格”的过滤条件，获取当前节点的所有子节点
            //  “左右值”过滤条件（同一根节点下，大于等于左值，小于等于右值）
            this.searchData.filterData.rootIsn = {
                expression: QueryFilter.EQUAL,
                value: node.rootIsn
            };
            this.searchData.filterData.leftValue = {
                expression: QueryFilter.GREATER_THAN_OR_EQUAL,
                value: node.leftValue
            };
            this.searchData.filterData.rightValue = {
                expression: QueryFilter.LESS_THAN_OR_EQUAL,
                value: node.rightValue
            }

        } else if (categoryField) {
            // 如果左侧分类是“树状结构”数据，则根据当前节点，获取子节点
            if (treeCategory) {
                const queryConf = new QueryDataConf();
                queryConf.filter = new QueryFilter(QueryFilter.AND);
                queryConf.filter.andEqual('parentIsn', node.isn);
                this.fetchTreeCate(queryConf, node);
            }

            // 构建右侧表格的对应筛选条件
            // 如果 categorySelector 有值，说明是枚举类型的分类，取 code 值
            let val = categorySelector ? node.code : node.id;
            // 如果 categoryType 是以 'com.jianhui' 开头，说明是对象类型，需要拼接 '.id'
            let cateKey = isString(categoryType) && categoryType.indexOf('com.jianhui') === 0 ? `${categoryField}.id` : categoryField;
            this.searchData.filterData[cateKey] = {
                expression: QueryFilter.EQUAL,
                value: val
            }
        }

        this.fetchList();
    }

    /**
     * 当选中数据有变化时的回调
     * @param selectedRowKeys
     * @param selectedRows
     * @param moreProps
     */
    hdlChangeTable(selectedRowKeys, selectedRows, moreProps) {
        if (this.isMulti()) {
            const {selected} = moreProps || {};
            if (selected) { // 如果是“选中操作”，将新选中的记录合并到 selectedRows
                this.selectedRows = unionWith(
                    this.selectedRows,
                    selectedRows,
                    (row1, row2) => (row1.id === row2.id)
                );
            } else { // 取消选中
                const {changeRows} = moreProps || {};
                this.selectedRows = filter(this.selectedRows, (row) => (
                    -1 === findIndex(changeRows, (cRow) => (cRow.id === row.id))
                ));
            }
        } else {
            this.selectedRows = selectedRows;
        }
        // console.log(`hdlChangeTable this.selectedRows:`, this.selectedRows);
    }

    /**
     * 选中/取消选中之后的回调(已选中的表格)
     * @param selectedRowKeys
     * @param selectedRows
     */
    hdlChangeTable2(selectedRowKeys, selectedRows) {
        this.selectedBtnIns.setCompProps({cnt: selectedRows.length})
    }

    /**
     * 表格-搜索
     * @param value
     */
    hdlTableSearch(value) {
        // console.log('value', value);
        this.searchData.search = value;
        this.hdlChangePage(1, this.state.listPage.pageSize);
    }

    /**
     * 表格-改变分页
     * @param page
     * @param pageSize
     */
    hdlChangePage(page, pageSize) {

        this.setState({
            listPage: {
                ...this.state.listPage,
                current: page,
                pageSize
            }
        }, () => {
            let appDendroid = this.getPropsByName('appDendroid') || this.finderConf.appDendroid;
            // appDendroid=true，说明查找器本身是“树状结构”数据，如果没有选中左侧节点，则不发请求
            if (appDendroid && isEmpty(this.searchData.filterData)) {
                jhMessage.warn(this.myFormatMessage('finder.choose.node'));
                return false;
            }

            this.fetchList();
        });
    }

    /**
     * 点击右上角的">>"按钮，即点击跳转到应用列表
     */
    hdlDoubleArrow() {
        const {appins, finderCode} = this.getProps();
        const appCode = this.appCode4Finder;

        if (appins && appins.onFinderAction) {
            appins.onFinderAction({type: 'list', appCode, finderCode});
        }
        // 关闭弹框
        this.runPropsFunc('onCancel')();
    }

    /**
     * 查看已选择的数据
     */
    hdlViewSelected() {
        if (this.selectedTableIns) {
            this.selectedTableIns.setSelectedKeys(map(this.selectedRows, (row) => (row.id)));
        }
        this.setState({activeTabKey: 'selected'});
    }

    /**
     * 确定选择
     */
    hdlOk() {

        if ('list' !== this.state.activeTabKey) {
            // 在“已选列表”中点击“确认”
            this.selectedRows = this.selectedTableIns.getSelected();
            // console.log('this.selectedRows', this.selectedRows);
            this.tableIns.setSelectedKeys(map(this.selectedRows, (row) => (row.id)), () => {
                this.setState({activeTabKey: 'list'});
            });
        } else {
            // const multi = this.isMulti();
            let selectedRows = this.selectedRows;

            // if (!multi) { // 单选，则直接获取当前表格的选中记录
            //             //     selectedRows = this.tableIns.getSelected();
            //             // }

            // console.log('selectedRows', selectedRows);
            this.runPropsFunc('onOk')(selectedRows);
        }
    }

    /**
     * 取消选择
     */
    hdlCancel() {
        if ('list' !== this.state.activeTabKey) {
            this.selectedBtnIns.setCompProps({cnt: this.selectedRows.length});
            this.setState({activeTabKey: 'list'});
        } else {
            this.runPropsFunc('onCancel')();
        }
    }

    /**
     * 将“查找器配置”转成“表格-列配置”
     * @return {[]} 表格-列配置
     * @private
     */
    _fields2Cols() {
        let codeDesc = this.formatMsgByCn('编码');
        let nameDesc = this.formatMsgByCn('名称');
        const finderConf = this.finderConf;
        const cols = finderConf && !isEmpty(finderConf.fields) ? finderConf.fields : [
            {
                desc: codeDesc,
                fieldName: 'code',
                componentType: ComponentType.TEXT_INPUT,
                visible: true,
                fieldWidth: 200
            },
            {
                desc: nameDesc,
                fieldName: 'name',
                componentType: ComponentType.TEXT_INPUT,
                visible: true,
                fieldWidth: 200
            },
        ];
        const reCols = [];
        map(cols, (col) => {
            if (!isEmpty(col) && col.visible) {
                reCols.push({
                    remark: col.desc,
                    name: col.fieldName,
                    colWidth: col.fieldWidth,
                    // orderBy: col.orderBy,
                    // sortable: col.sortable,
                    // visible: col.visible,
                    dataType: col.dataType,
                    componentType: col.componentType,
                });
            }
        });
        return reCols;
    }

    contentH = 500;

    // 用于设置自定义扩展字段的表格
    extendedRender() {
        return null;
    }

    mainRender(context) {
        const {
            title, visible,
            style, multi,
            cateTreeProps = {},
            tableProps = {}
        } = this.getProps();
        const appCode = this.appCode4Finder;
        const {categorized} = this.finderConf;
        const tableCols = this._fields2Cols();
        const selectedStyle = {};

        if (false === multi) {
            selectedStyle.display = 'none';
        }

        const modalTitle = (appCode && title && '-' !== title) ? (
            <span className={styles.tl}
                  title={this.myFormatMessage('act.view.all', {name: title})}
                  onClick={(e) => {
                      e.preventDefault();
                      this.hdlDoubleArrow();
                  }}>{title}<DoubleRightOutlined style={{marginLeft: 8}}/></span>
        ) : (title || '-');

        return (
            <ModalComp
                title={modalTitle}
                visible={visible}
                loading={this.state.loading}
                // onOk={this.hdlOk.bind(this)}
                onCancel={this.hdlCancel.bind(this)}
                width={900}
                bodyStyle={{padding: '0 0 4px 0'}}
                footer={[
                    <SelectedBtn
                        key="selected"
                        onRef={(ref) => {
                            this.selectedBtnIns = ref;
                        }}
                        disabled={'list' !== this.state.activeTabKey}
                        cnt={this.selectedRows.length}
                        style={selectedStyle}
                        onClick={this.hdlViewSelected.bind(this)}
                    />,
                    <Button key="cancel" onClick={this.hdlCancel.bind(this)}>
                        {this.formatMsgByCn('取消')}
                    </Button>,
                    <Button key="ok" type="primary"
                            disabled={this.state.loading}
                            onClick={this.hdlOk.bind(this)}
                    >
                        {this.formatMsgByCn('确定')}
                    </Button>,
                ]}
            >
                <Tabs activeKey={this.state.activeTabKey} tabBarStyle={{display: 'none'}}>
                    <TabPane tab="list" key="list">
                        <Tabs tabBarStyle={{padding: '0 8px', ...this.state.extendedEnable && {} || {display: 'none'}}}>
                            <TabPane tab={this.formatMsgByCn('元数据')} key="meta" forceRender={true}>
                                <Row style={{flexFlow: 'nowrap', height: this.contentH, ...(style || {})}}>
                                    {
                                        categorized && (
                                            <Col flex={'250px'} style={{paddingLeft: 8, paddingBottom: 8}}>
                                                <TreeComp
                                                    style={{height: '100%'}}
                                                    border={true}
                                                    {...cateTreeProps}
                                                    onSearch={this.fetchCateList.bind(this)}
                                                    loading={this.state.cateLoading}
                                                    onRef={(ref) => {
                                                        this.treeIns = ref;
                                                    }}
                                                    afterSelect={this.hdlSelectNode.bind(this)}
                                                />
                                            </Col>
                                        )
                                    }

                                    <Col flex={'auto'} style={{padding: '0 8px', overflow: 'auto'}}>
                                        <Row justify="space-around" align="middle"
                                             style={{flexFlow: 'nowrap', height: 40}}>
                                            <Col flex={'250px'}>
                                                <Search
                                                    style={{width: '100%'}}
                                                    placeholder={this.myFormatMessage('comp.search.placeholder')}
                                                    onSearch={this.hdlTableSearch.bind(this)}
                                                    onKeyDown={(e) => {
                                                        e.stopPropagation();
                                                    }}
                                                />
                                            </Col>
                                            <Col flex={'auto'} style={{textAlign: 'right'}}>
                                                <Pagination size={"small"}
                                                            simple
                                                            {...this.state.listPage}
                                                            onChange={this.hdlChangePage.bind(this)}/>
                                            </Col>
                                            {
                                                // appCode && (
                                                //     <Col>
                                                //         <Button
                                                //             type={"link"}
                                                //             onClick={this.hdlDoubleArrow.bind(this)}
                                                //             style={{
                                                //                 paddingLeft: 8,
                                                //                 paddingRight: 8,
                                                //                 marginLeft: 8
                                                //             }}>
                                                //             <DoubleRightOutlined/>
                                                //         </Button>
                                                //     </Col>
                                                // )
                                            }
                                        </Row>
                                        <TableComp
                                            style={{height: 'calc(100% - 40px)'}}
                                            selecting={true}
                                            rowSelect={true}
                                            rowSelection={{
                                                onChange: this.hdlChangeTable.bind(this),
                                            }}
                                            multi={multi}
                                            needNO={true}
                                            {...tableProps}
                                            onRowProps={{
                                                ...(tableProps.onRowProps || {}),
                                                /**
                                                 * 双击行
                                                 * @param e
                                                 * @param record
                                                 */
                                                onDoubleClick: (e, record) => {
                                                    // 如果是单选模式，则直接确认选中当前记录
                                                    if (!this.isMulti()) {
                                                        this.hdlOk();
                                                    }

                                                    const {onDoubleClick} = tableProps.onRowProps || {};
                                                    isFunction(onDoubleClick) && onDoubleClick(e, record);
                                                }
                                            }}
                                            onRef={(ref) => {
                                                this.tableIns = ref;
                                                ref.setSelectedKeys(map(this.selectedRows, (row) => (row.id)));
                                            }}
                                            colsConf={tableCols}
                                            pagination={false}
                                            loading={this.state.listLoading}
                                            // pagination={{
                                            //     position: ['topRight'],
                                            //     size: "small",
                                            //     simple: true,
                                            //     style:{margin: '5px 0'},
                                            //     // total: 0, // 总记录数
                                            //     // pageSize: 40, // 每页显示的记录数
                                            //     // current: 1, // 当前页
                                            // }}
                                        />
                                    </Col>
                                </Row>
                            </TabPane>
                            {
                                this.extendedRender()
                            }
                        </Tabs>
                    </TabPane>
                    <TabPane tab="selected" key="selected">
                        <div style={{padding: 8}}>
                            <TableComp
                                style={{height: this.contentH - 16}}
                                selecting={true}
                                rowSelect={true}
                                rowSelection={{
                                    onChange: this.hdlChangeTable2.bind(this),
                                }}
                                multi={multi}
                                needNO={true}
                                onRef={(ref) => {
                                    this.selectedTableIns = ref;
                                    ref.setSelectedKeys(map(this.selectedRows, (row) => (row.id)));
                                }}
                                colsConf={tableCols}
                                dataSource={[...this.selectedRows]}
                                pagination={{
                                    pageSize: 20,
                                    position: ['bottomCenter'],
                                    size: "small",
                                    // simple: true,
                                    style: {margin: '5px 0'}
                                }}
                            />
                        </div>
                    </TabPane>
                </Tabs>

            </ModalComp>
        )
    };

}

class SelectedBtn extends BaseComp {

    mainRender() {
        const {cnt = 0, onRef, ...restProps} = this.getProps();
        return (
            <Button type="link"
                    {...restProps}
            >
                {this.formatMsgByCn('已选择')} ({cnt})
            </Button>
        )
    }
}